// 
//  Copyright © 2009 Jiří Zárevúcky <zarevucky.jiri@gmail.com>
// 
//  This program is free software: you can redistribute it and/or modify
//  it under the terms of the GNU Affero General Public License as
//  published by the Free Software Foundation, either version 3 of the
//  License, or (at your option) any later version.
// 
//  This program is distributed in the hope that it will be useful,
//  but WITHOUT ANY WARRANTY; without even the implied warranty of
//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//  GNU Affero General Public License for more details.
// 
//  You should have received a copy of the GNU Affero General Public License
//  along with this program.  If not, see <http://www.gnu.org/licenses/>.
// 
// 

using System;
using System.Collections.Generic;

using Galaxium.Protocol.Xmpp.Library.Core;
using Galaxium.Protocol.Xmpp.Library.Utility;

namespace Galaxium.Protocol.Xmpp.Library
{
	public enum Status {
		Offline, Unknown, Updating, Error, XA, Dnd, Away, Online, Chat
	}

	public static class StatusMethods
	{
		private static List<sbyte?> s_default_priorities;
		private static List<string> s_human_texts; 
		
		public static List<sbyte?> DefaultPriorities {
			get { return s_default_priorities; }
		}
		
		static StatusMethods ()
		{
			s_default_priorities = new List<sbyte?> () {
				null, null, null, null, 10, 20, 30, 40, 50
			};

			s_human_texts = new List<string> () {
				"Offline", "Unknown", "Updating...", "Error", "Extended Away",
				"Do Not Disturb", "Away", "Online", "Free For Chat"
			};
		}
		
		public static Presence ToPresence (Status status, string description, sbyte? priority)
		{
			Presence pres;
			if (status == Status.Error || status == Status.Unknown || status == Status.Updating) {
				throw new ArgumentException ("You can't use these values to create a presence", "status");
			} else if (status == Status.Offline) {
				pres = new Presence (PresType.Unavailable, null);
				pres.AppendStatus (description);
			} else {
				string show = (status == Status.Online) ? null : status.ToString ().ToLower ();
				pres = new Presence (show, description, priority ?? s_default_priorities [(int) status]);
			}
			return pres;
		}
		
		public static string GetHumanRepresentation (Status status)
		{
			return s_human_texts [(int) status];
		}

		
		public static Status GetPresenceStatus (Presence pres)
		{
			return (Status) Enum.Parse (typeof (Status), pres.GetTextRepresentation (), true);
		}

		public static Status GetStatus (Contact contact)
		{
			if (contact.IsOnline || contact.MainPresence.IsError)
				return StatusMethods.GetPresenceStatus (contact.MainPresence);
			
			if (contact.IsSubscribed)
				return Status.Offline;
			
			return Status.Unknown;
		}

		public static string GetHumanRepresentation (Presence pres)
		{
			return StatusMethods.GetHumanRepresentation (StatusMethods.GetPresenceStatus (pres));
		}
	}
}
